package com.fusion.launchers.testsuite;

import com.fusion.T;
import com.fusion.core.CoreSubsystem;
import com.fusion.core.ResourceSingelton;
import com.fusion.ui.UISubsystem;
import com.stendahls.XUI.XUIFrame;
import com.stendahls.trace.Trace;
import com.stendahls.trace.TraceHandler;


import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.HashMap;


/**
 * @author SwethaShivakumar 
 * Project: fusion
 * Date: Mar 17, 2009
 * URL: http://fusionwiki.co.cc
 * Mail Me At: shiva@fusionproject.co.cc
 */
public class Main {
    public static final boolean LOG_TO_FILES = false;

    private static HashMap<String, Main> users = new HashMap<String, Main>();

    private CoreSubsystem core;
    private UISubsystem ui;
    private String settings;

    private static JList list;

    public Main() {
    }

    public Main(String settings) throws Exception {
        System.out.println("  "+settings);
        this.settings = settings;
        launchCore();
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Welcome to Fusion testsuite. Launching:");

        System.setProperty("testsuite", "true");

        for(File f : new File("testsuite/logs").listFiles()) f.delete();

        if (T.t) {
            Trace.handler = new TraceHandler() {
                private HashMap<String, BufferedWriter> logs = new HashMap<String, BufferedWriter>();

                public void print(int level, Object o, Exception error) {
                    try {
                        String message = String.valueOf(o);
                        String name = Thread.currentThread().getName();
                        // String module = message.substring(0, message.indexOf(' '));

                        if (level >= Trace.LEVEL_WARN) System.out.println(message+" ("+name+")");

                        if (LOG_TO_FILES) {
                            BufferedWriter out;
                            if (logs.containsKey(name)) {
                                out = logs.get(name);
                            } else {
                                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("testsuite/logs/"+name+".log")));
                                logs.put(name, out);
                            }
                            out.write(message+"\r\n");
                            out.flush();
                        }

                        int i = name.indexOf("--");
                        if (i != -1) {
                            name = name.substring(i+3);
                            Main m = users.get(name.toLowerCase());
//                            System.out.println(name+" "+message);
                            if (m != null) {
                                if (error == null) error = new Exception();
                                m.core.propagateTraceMessage(level, String.valueOf(message), error);
                            }
                        } else {
                        }

                    } catch(IOException e) {
                        e.printStackTrace();
                    }
                }
            };
        }

        XUIFrame frame = new XUIFrame("testsuite/testsuite.xui.xml");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getXUI().setEventHandler(new Main());
        list = new JList(new DefaultListModel());
        JScrollPane p = (JScrollPane)frame.getXUI().getComponent("sp");
        p.setViewportView(list);
        frame.display();
        list.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (list.getSelectedValue() != null && e.getClickCount() > 1) {
                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            try {
                                Main m = (Main)list.getSelectedValue();
                                m.launchUI();
                            } catch (Exception e1) {
                                e1.printStackTrace();
                            }
                        }
                    });
                    t.start();
                }
            }
        });

        File settings[] = new File("testsuite/settings").listFiles();
        for(File f : settings) {
            if (f.toString().endsWith("xml")) {
                final Main m = new Main(f.toString());
                users.put(f.toString().substring(f.toString().lastIndexOf(System.getProperty("file.separator"))+1, f.toString().lastIndexOf('.')).toLowerCase(), m);
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        ((DefaultListModel)list.getModel()).addElement(m);
                    }
                });
            }
            Thread.sleep((long)(1000));
        }
    }

    private void launchUI() throws Exception {
        if (core == null) launchCore();
        ui = new UISubsystem();
        ui.init(ResourceSingelton.getRl(), core);
    }

    private void launchCore() throws Exception {
        if (core != null) shutdown();
        core = new CoreSubsystem();
        core.init(ResourceSingelton.getRl(), settings);
    }

    private void shutdown() {
        if (ui != null) ui.shutdown();
        if (core != null) core.shutdown();
        ui = null;
        core = null;
    }

    public String toString() {
        return settings;
    }

    public void EVENT_openui(ActionEvent e) throws Exception {
        Main m = (Main)list.getSelectedValue();
        if (m != null) m.launchUI();
    }

    public void EVENT_start(ActionEvent e) throws Exception {
        Main m = (Main)list.getSelectedValue();
        if (m != null) m.launchCore();
    }

    public void EVENT_stop(ActionEvent e) throws Exception {
        Main m = (Main)list.getSelectedValue();
        if (m != null) m.shutdown();
    }
}
